package com.lc1993929.tank.map;

import com.lc1993929.tank.constants.Condition;
import com.lc1993929.tank.constants.Direction;
import com.lc1993929.tank.constants.MapElement;
import com.lc1993929.tank.entity.tank.Tank;
import com.lc1993929.tank.entity.vo.CoordAndValue;
import com.lc1993929.tank.entity.vo.MapElementAndDirection;
import com.lc1993929.tank.util.MapUtil;
import com.lc1993929.tank.util.Util;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.lc1993929.tank.constants.MapElement.*;

/**
 * ClassName: MapInfo
 *
 * @author kesar
 * @Description: 包含地图所需的所有输入数据
 */
public class GameMap {

    public Map<Coord, MapElement> maps; // 二维数组的地图
    public Integer[][] enemyValueMap; // 敌方价值地图
    public Integer[][] myValueMap;//我方价值地图
    public int width; // 地图的宽
    public int hight; // 地图的高
    public Node start; // 起始结点
    public Node end; // 最终结点

    public GameMap(Map<Coord, MapElement> maps, Integer[][] enemyValueMap, Integer[][] myValueMap, int width, int hight) {
        this.maps = maps;
        this.enemyValueMap = enemyValueMap;
        this.myValueMap = myValueMap;
        this.width = width;
        this.hight = hight;
    }

    public void clearEnemyValueMap() {
        for (int x = 0; x < enemyValueMap.length; x++) {
            Integer[] ys = enemyValueMap[x];
            for (int y = 0; y < ys.length; y++) {
                enemyValueMap[x][y] = 0;
            }
        }
    }

    public void clearMyValueMap() {
        for (int x = 0; x < myValueMap.length; x++) {
            Integer[] ys = myValueMap[x];
            for (int y = 0; y < ys.length; y++) {
                myValueMap[x][y] = 0;
            }
        }
    }

    public void updateByEnemyTank(Tank tank) {
        Coord coord = tank.coord;
        for (int i = 0; i < 4; i++) {
            //威胁有4个方向
            for (int j = 1; j < tank.shecheng + 1; j++) {
                //左
                if (i == 0) {
                    int integer = enemyCanHaveValue(coord.x - j, coord.y);
                    if (integer == 2) {
                        enemyValueMap[coord.x - j][coord.y] = enemyValueMap[coord.x - j][coord.y] + tank.gongji;
                    } else if (integer == 1) {
                        enemyValueMap[coord.x - j][coord.y] = enemyValueMap[coord.x - j][coord.y] + tank.gongji;
                        break;
                    } else {
                        break;
                    }
                } else if (i == 1) {
                    //    右
                    int integer = enemyCanHaveValue(coord.x + j, coord.y);
                    if (integer == 2) {
                        enemyValueMap[coord.x + j][coord.y] = enemyValueMap[coord.x + j][coord.y] + tank.gongji;
                    } else if (integer == 1) {
                        enemyValueMap[coord.x + j][coord.y] = enemyValueMap[coord.x + j][coord.y] + tank.gongji;
                        break;
                    } else {
                        break;
                    }
                } else if (i == 2) {
                    //    上
                    Integer integer = enemyCanHaveValue(coord.x, coord.y - j);
                    if (integer == 2) {
                        enemyValueMap[coord.x][coord.y - j] = enemyValueMap[coord.x][coord.y - j] + tank.gongji;
                    } else if (integer == 1) {
                        enemyValueMap[coord.x][coord.y - j] = enemyValueMap[coord.x][coord.y - j] + tank.gongji;
                        break;
                    } else {
                        break;
                    }
                } else {
                    //    下
                    Integer integer = enemyCanHaveValue(coord.x, coord.y + j);
                    if (integer == 2) {
                        enemyValueMap[coord.x][coord.y + j] = enemyValueMap[coord.x][coord.y + j] + tank.gongji;
                    } else if (integer == 1) {
                        enemyValueMap[coord.x][coord.y + j] = enemyValueMap[coord.x][coord.y + j] + tank.gongji;
                        break;
                    } else {
                        break;
                    }
                }
            }
        }
    }

    public void updateByAllEnemyTank() {
        if (Condition.enemyArmata1.coord != null && Condition.enemyArmata1.shengyushengming > 0) {
            updateByEnemyTank(Condition.enemyArmata1);
        }
        if (Condition.enemyArmata2.coord != null && Condition.enemyArmata2.shengyushengming > 0) {
            updateByEnemyTank(Condition.enemyArmata2);
        }
        if (Condition.enemyK2Panther.coord != null && Condition.enemyK2Panther.shengyushengming > 0) {
            updateByEnemyTank(Condition.enemyK2Panther);
        }
        if (Condition.enemyT90.coord != null && Condition.enemyT90.shengyushengming > 0) {
            updateByEnemyTank(Condition.enemyT90);
        }
        if (Condition.enemyWZ123.coord != null && Condition.enemyWZ123.shengyushengming > 0) {
            updateByEnemyTank(Condition.enemyWZ123);
        }
    }

    public void updateByMyTank(Tank tank) {
        Coord coord = tank.coord;
        for (int i = 0; i < 4; i++) {
            //威胁有4个方向
            for (int j = 1; j < tank.shecheng + 1; j++) {
                //左
                if (i == 0) {
                    int integer = myCanHaveValue(coord.x - j, coord.y);
                    if (integer == 2) {
                        myValueMap[coord.x - j][coord.y] = myValueMap[coord.x - j][coord.y] + tank.gongji;
                    } else if (integer == 1) {
                        myValueMap[coord.x - j][coord.y] = myValueMap[coord.x - j][coord.y] + tank.gongji;
                        break;
                    } else {
                        break;
                    }
                } else if (i == 1) {
                    //    右
                    int integer = myCanHaveValue(coord.x + j, coord.y);
                    if (integer == 2) {
                        myValueMap[coord.x + j][coord.y] = myValueMap[coord.x + j][coord.y] + tank.gongji;
                    } else if (integer == 1) {
                        myValueMap[coord.x + j][coord.y] = myValueMap[coord.x + j][coord.y] + tank.gongji;
                        break;
                    } else {
                        break;
                    }
                } else if (i == 2) {
                    //    上
                    Integer integer = myCanHaveValue(coord.x, coord.y - j);
                    if (integer == 2) {
                        myValueMap[coord.x][coord.y - j] = myValueMap[coord.x][coord.y - j] + tank.gongji;
                    } else if (integer == 1) {
                        myValueMap[coord.x][coord.y - j] = myValueMap[coord.x][coord.y - j] + tank.gongji;
                        break;
                    } else {
                        break;
                    }
                } else {
                    //    下
                    Integer integer = myCanHaveValue(coord.x, coord.y + j);
                    if (integer == 2) {
                        myValueMap[coord.x][coord.y + j] = myValueMap[coord.x][coord.y + j] + tank.gongji;
                    } else if (integer == 1) {
                        myValueMap[coord.x][coord.y + j] = myValueMap[coord.x][coord.y + j] + tank.gongji;
                        break;
                    } else {
                        break;
                    }
                }
            }
        }
    }

    /**
     * 移动时删除坦克的威胁值
     */
    public void updateByMyTankMove(Tank tank) {
        Coord coord = tank.coord;
        for (int i = 0; i < 4; i++) {
            //威胁有4个方向
            for (int j = 1; j < tank.shecheng + 1; j++) {
                //左
                if (i == 0) {
                    int integer = myCanHaveValue(coord.x - j, coord.y);
                    if (integer == 2) {
                        myValueMap[coord.x - j][coord.y] = myValueMap[coord.x - j][coord.y] - tank.gongji;
                    } else if (integer == 1) {
                        myValueMap[coord.x - j][coord.y] = myValueMap[coord.x - j][coord.y] - tank.gongji;
                        break;
                    } else {
                        break;
                    }
                } else if (i == 1) {
                    //    右
                    int integer = myCanHaveValue(coord.x + j, coord.y);
                    if (integer == 2) {
                        myValueMap[coord.x + j][coord.y] = myValueMap[coord.x + j][coord.y] - tank.gongji;
                    } else if (integer == 1) {
                        myValueMap[coord.x + j][coord.y] = myValueMap[coord.x + j][coord.y] - tank.gongji;
                        break;
                    } else {
                        break;
                    }
                } else if (i == 2) {
                    //    上
                    Integer integer = myCanHaveValue(coord.x, coord.y - j);
                    if (integer == 2) {
                        myValueMap[coord.x][coord.y - j] = myValueMap[coord.x][coord.y - j] - tank.gongji;
                    } else if (integer == 1) {
                        myValueMap[coord.x][coord.y - j] = myValueMap[coord.x][coord.y - j] - tank.gongji;
                        break;
                    } else {
                        break;
                    }
                } else {
                    //    下
                    Integer integer = myCanHaveValue(coord.x, coord.y + j);
                    if (integer == 2) {
                        myValueMap[coord.x][coord.y + j] = myValueMap[coord.x][coord.y + j] - tank.gongji;
                    } else if (integer == 1) {
                        myValueMap[coord.x][coord.y + j] = myValueMap[coord.x][coord.y + j] - tank.gongji;
                        break;
                    } else {
                        break;
                    }
                }
            }
        }
    }

    public void updateByAllMyTank() {
        if (Condition.myArmata1.shengyushengming > 0) {
            updateByMyTank(Condition.myArmata1);
        }
        if (Condition.myArmata2.shengyushengming > 0) {
            updateByMyTank(Condition.myArmata2);
        }
        if (Condition.myK2Panther.shengyushengming > 0) {
            updateByMyTank(Condition.myK2Panther);
        }
        if (Condition.myT90.shengyushengming > 0) {
            updateByMyTank(Condition.myT90);
        }
        if (Condition.myWZ123.shengyushengming > 0) {
            updateByMyTank(Condition.myWZ123);
        }
    }

    /**
     * 找到目标坐标的敌方威胁值
     */
    public Integer getEnemyValue(Coord coord) {
        if (coord.x < 0 || coord.x >= width || coord.y < 0 || coord.y >= hight) {
            return Integer.MAX_VALUE;
        }
        return enemyValueMap[coord.x][coord.y];
    }

    /**
     * 找到目标坐标的我方威胁值
     */
    public Integer getMyValue(Coord coord) {
        if (coord.x < 0 || coord.x >= width || coord.y < 0 || coord.y >= hight) {
            return Integer.MIN_VALUE;
        }
        return myValueMap[coord.x][coord.y];
    }


    //返回0：不可穿过，1：可攻击不可穿过，2：可穿过
    public Integer enemyCanHaveValue(Integer x, Integer y) {
        // 是否在地图中
        if (x < 0 || x >= width || y < 0 || y >= hight) {
            return 0;
        }
        MapElement mapElement = maps.get(new Coord(x, y));
        if (mapElement == BAR) {
            return 0;
        }
        if (mapElement == NPC) {
            return 1;
        }
        return 2;
    }

    public int myCanHaveValue(int x, int y) {
        // 是否在地图中
        if (x < 0 || x >= width || y < 0 || y >= hight) {
            return 0;
        }
        MapElement mapElement = maps.get(new Coord(x, y));
        if (mapElement == MapElement.BAR) {
            return 0;
        }
        if (mapElement == MapElement.ENEMY_ARMATA1
                || mapElement == MapElement.ENEMY_ARMATA2
                || mapElement == MapElement.ENEMY_K2PANTHER
                || mapElement == MapElement.ENEMY_T90
                || mapElement == MapElement.NPC
                || mapElement == MapElement.ENEMY_WZ123) {
            return 1;
        }
        return 2;
    }


    /**
     * 找一个死角
     */
    public Coord findADeadAngle() {
        //3面有障碍的集合
        List<Coord> bar3List = new ArrayList<>();
        //2面有障碍的集合
        List<Coord> bar2List = new ArrayList<>();
        maps.forEach((coord, mapElement) -> {
            int i = 0;
            if (maps.get(new Coord(coord.x - 1, coord.y)) == MapElement.BAR || coord.x - 1 < 0) {
                i++;
            }
            if (maps.get(new Coord(coord.x + 1, coord.y)) == MapElement.BAR || coord.x + 1 >= width) {
                i++;
            }
            if (maps.get(new Coord(coord.x, coord.y - 1)) == MapElement.BAR || coord.y - 1 < 0) {
                i++;
            }
            if (maps.get(new Coord(coord.x, coord.y + 1)) == MapElement.BAR || coord.y + 1 >= hight) {
                i++;
            }
            if (i == 3) {
                bar3List.add(coord);
            } else if (i == 2) {
                bar2List.add(coord);
            }
        });
        if (!bar3List.isEmpty()) {
            return bar3List.get(Util.getRandom(bar3List.size()));
        } else {
            return bar2List.get(Util.getRandom(bar2List.size()));
        }
    }

    /**
     * 判断敌方坦克能否攻击到指定位置
     */
    public boolean enemyCanAttack(Tank tank, Coord coord) {
        if (tank.shengyushengming <= 0) {
            return false;
        }
        if (tank.coord.x == coord.x) {
            //横坐标相同，比较纵坐标
            if (tank.shecheng >= Math.abs(tank.coord.y - coord.y)) {
                //坦克的坐标与目标点的横坐标距离相差比坦克的射程小
                if (tank.coord.y > coord.y) {
                    for (int i = 1; i < tank.shecheng + 1; i++) {
                        if (coord.y == tank.coord.y - i) {
                            return true;
                        }
                        int integer = enemyCanHaveValue(tank.coord.x, tank.coord.y - i);
                        if (integer == 0 || integer == 1) {
                            return false;
                        }
                    }
                } else {
                    for (int i = 1; i < tank.shecheng + 1; i++) {
                        if (coord.y == tank.coord.y + i) {
                            return true;
                        }
                        int integer = enemyCanHaveValue(tank.coord.x, tank.coord.y + i);
                        if (integer == 0 || integer == 1) {
                            return false;
                        }
                    }
                }
            }
        } else if (tank.coord.y == coord.y) {
            //纵坐标相同，比较横坐标
            if (tank.shecheng >= Math.abs(tank.coord.x - coord.x)) {
                //坦克的坐标与目标点的横坐标距离相差比坦克的射程小
                if (tank.coord.x > coord.x) {
                    for (int i = 1; i < tank.shecheng + 1; i++) {
                        if (coord.x == tank.coord.x - i) {
                            return true;
                        }
                        int integer = enemyCanHaveValue(tank.coord.x - i, tank.coord.y);
                        if (integer == 0 || integer == 1) {
                            return false;
                        }
                    }
                } else {
                    for (int i = 1; i < tank.shecheng + 1; i++) {
                        if (coord.x == tank.coord.x + i) {
                            return true;
                        }
                        int integer = enemyCanHaveValue(tank.coord.x + i, tank.coord.y);
                        if (integer == 0 || integer == 1) {
                            return false;
                        }
                    }
                }
            }
        } else {
            //横坐标、纵坐标都不相等，无法攻击到
            return false;
        }
        return false;
    }

    /**
     * 获取坦克移动范围内的最优点
     */
    public Coord myBestCoord(Tank tank) {
        Coord coord = tank.coord;
        Coord bestCoord = coord;
        Integer bestValue = MapUtil.getCanBeAttackNum(coord);
        for (int i = 0; i < 4; i++) {
            //威胁有4个方向
            for (int j = 1; j < tank.yidong + 1; j++) {
                //左
                if (i == 0) {
                    Coord myTankCoord = new Coord(coord.x - j, coord.y);
                    MapElement mapElement = maps.get(myTankCoord);
                    if (mapElement == BAR || mapElement == ENEMY_ARMATA1 || mapElement == ENEMY_ARMATA2 || mapElement == ENEMY_K2PANTHER || mapElement == ENEMY_T90 || mapElement == ENEMY_WZ123
                            || mapElement == MY_ARMATA1 || mapElement == MY_ARMATA2 || mapElement == MY_K2PANTHER || mapElement == MY_T90 || mapElement == MY_WZ123 || mapElement == null) {
                        break;
                    } else {
                        Integer canBeAttackNum = MapUtil.getCanBeAttackNum(myTankCoord);
                        if (mapElement == WAY && canBeAttackNum < bestValue) {
                            bestValue = canBeAttackNum;
                            bestCoord = myTankCoord;
                        }
                    }
                } else if (i == 1) {
                    //    右
                    Coord myTankCoord = new Coord(coord.x + j, coord.y);
                    MapElement mapElement = maps.get(myTankCoord);
                    if (mapElement == BAR || mapElement == ENEMY_ARMATA1 || mapElement == ENEMY_ARMATA2 || mapElement == ENEMY_K2PANTHER || mapElement == ENEMY_T90 || mapElement == ENEMY_WZ123
                            || mapElement == MY_ARMATA1 || mapElement == MY_ARMATA2 || mapElement == MY_K2PANTHER || mapElement == MY_T90 || mapElement == MY_WZ123 || mapElement == null) {
                        break;
                    } else {
                        Integer canBeAttackNum = MapUtil.getCanBeAttackNum(myTankCoord);
                        if (mapElement == WAY && canBeAttackNum < bestValue) {
                            bestValue = canBeAttackNum;
                            bestCoord = myTankCoord;
                        }
                    }
                } else if (i == 2) {
                    //    下
                    Coord myTankCoord = new Coord(coord.x, coord.y - j);
                    MapElement mapElement = maps.get(myTankCoord);
                    if (mapElement == BAR || mapElement == ENEMY_ARMATA1 || mapElement == ENEMY_ARMATA2 || mapElement == ENEMY_K2PANTHER || mapElement == ENEMY_T90 || mapElement == ENEMY_WZ123
                            || mapElement == MY_ARMATA1 || mapElement == MY_ARMATA2 || mapElement == MY_K2PANTHER || mapElement == MY_T90 || mapElement == MY_WZ123 || mapElement == null) {
                        break;
                    } else {
                        Integer canBeAttackNum = MapUtil.getCanBeAttackNum(myTankCoord);
                        if (mapElement == WAY && canBeAttackNum < bestValue) {
                            bestValue = canBeAttackNum;
                            bestCoord = myTankCoord;
                        }
                    }
                } else {
                    //    上
                    Coord myTankCoord = new Coord(coord.x, coord.y + j);
                    MapElement mapElement = maps.get(myTankCoord);
                    if (mapElement == BAR || mapElement == ENEMY_ARMATA1 || mapElement == ENEMY_ARMATA2 || mapElement == ENEMY_K2PANTHER || mapElement == ENEMY_T90 || mapElement == ENEMY_WZ123
                            || mapElement == MY_ARMATA1 || mapElement == MY_ARMATA2 || mapElement == MY_K2PANTHER || mapElement == MY_T90 || mapElement == MY_WZ123 || mapElement == null) {
                        break;
                    } else {
                        Integer canBeAttackNum = MapUtil.getCanBeAttackNum(myTankCoord);
                        if (mapElement == WAY && canBeAttackNum < bestValue) {
                            bestValue = canBeAttackNum;
                            bestCoord = myTankCoord;
                        }
                    }
                }
            }
        }
        return bestCoord;
    }

    /**
     * 获取坦克移动范围内的最优点的集合
     */
    public List<Coord> myBestCoords(Tank tank) {
        List<CoordAndValue> coordAndValues = new ArrayList<>();
        Coord coord = tank.coord;
        Integer bestValue = MapUtil.getCanBeAttackNum(coord);
        coordAndValues.add(CoordAndValue.builder().coord(coord).value(bestValue).build());
        for (int i = 0; i < 4; i++) {
            //威胁有4个方向
            for (int j = 1; j < tank.yidong + 1; j++) {
                //左
                if (i == 0) {
                    Coord myTankCoord = new Coord(coord.x - j, coord.y);
                    if (!MapUtil.coordCanArrive(myTankCoord)) {
                        break;
                    } else {
                        Integer canBeAttackNum = MapUtil.getCanBeAttackNum(myTankCoord);
                        if (canBeAttackNum <= coordAndValues.stream().min(Comparator.comparingInt(CoordAndValue::getValue)).get().getValue()) {
                            coordAndValues.add(CoordAndValue.builder().coord(myTankCoord).value(canBeAttackNum).build());
                        }
                    }
                } else if (i == 1) {
                    //    右
                    Coord myTankCoord = new Coord(coord.x + j, coord.y);
                    if (!MapUtil.coordCanArrive(myTankCoord)) {
                        break;
                    } else {
                        Integer canBeAttackNum = MapUtil.getCanBeAttackNum(myTankCoord);
                        if (canBeAttackNum <= coordAndValues.stream().min(Comparator.comparingInt(CoordAndValue::getValue)).get().getValue()) {
                            coordAndValues.add(CoordAndValue.builder().coord(myTankCoord).value(canBeAttackNum).build());
                        }
                    }
                } else if (i == 2) {
                    //    下
                    Coord myTankCoord = new Coord(coord.x, coord.y - j);
                    if (!MapUtil.coordCanArrive(myTankCoord)) {
                        break;
                    } else {
                        Integer canBeAttackNum = MapUtil.getCanBeAttackNum(myTankCoord);
                        if (canBeAttackNum <= coordAndValues.stream().min(Comparator.comparingInt(CoordAndValue::getValue)).get().getValue()) {
                            coordAndValues.add(CoordAndValue.builder().coord(myTankCoord).value(canBeAttackNum).build());
                        }
                    }
                } else {
                    //    上
                    Coord myTankCoord = new Coord(coord.x, coord.y + j);
                    if (!MapUtil.coordCanArrive(myTankCoord)) {
                        break;
                    } else {
                        Integer canBeAttackNum = MapUtil.getCanBeAttackNum(myTankCoord);
                        if (canBeAttackNum <= coordAndValues.stream().min(Comparator.comparingInt(CoordAndValue::getValue)).get().getValue()) {
                            coordAndValues.add(CoordAndValue.builder().coord(myTankCoord).value(canBeAttackNum).build());
                        }
                    }
                }
            }
        }
        Integer minValue = coordAndValues.stream().min(Comparator.comparingInt(CoordAndValue::getValue)).get().getValue();
        return coordAndValues.stream().filter(coordAndValue -> coordAndValue.getValue().equals(minValue)).map(CoordAndValue::getCoord)
                .collect(Collectors.toList());
    }

    /**
     * 获取坦克移动范围内的最优点的集合，除了坦克自己的点
     */
    public List<Coord> myBestCoordsExceptSelf(Tank tank) {
        List<CoordAndValue> coordAndValues = new ArrayList<>();
        Coord coord = tank.coord;
        for (int i = 0; i < 4; i++) {
            //威胁有4个方向
            for (int j = 1; j < tank.yidong + 1; j++) {
                //左
                if (i == 0) {
                    Coord myTankCoord = new Coord(coord.x - j, coord.y);
                    if (!MapUtil.coordCanArrive(myTankCoord)) {
                        break;
                    } else {
                        Integer canBeAttackNum = MapUtil.getCanBeAttackNum(myTankCoord);
                        if (coordAndValues.isEmpty() || canBeAttackNum <= coordAndValues.stream().min(Comparator.comparingInt(CoordAndValue::getValue)).get().getValue()) {
                            coordAndValues.add(CoordAndValue.builder().coord(myTankCoord).value(canBeAttackNum).build());
                        }
                    }
                } else if (i == 1) {
                    //    右
                    Coord myTankCoord = new Coord(coord.x + j, coord.y);
                    if (!MapUtil.coordCanArrive(myTankCoord)) {
                        break;
                    } else {
                        Integer canBeAttackNum = MapUtil.getCanBeAttackNum(myTankCoord);
                        if (coordAndValues.isEmpty() || canBeAttackNum <= coordAndValues.stream().min(Comparator.comparingInt(CoordAndValue::getValue)).get().getValue()) {
                            coordAndValues.add(CoordAndValue.builder().coord(myTankCoord).value(canBeAttackNum).build());
                        }
                    }
                } else if (i == 2) {
                    //    下
                    Coord myTankCoord = new Coord(coord.x, coord.y - j);
                    if (!MapUtil.coordCanArrive(myTankCoord)) {
                        break;
                    } else {
                        Integer canBeAttackNum = MapUtil.getCanBeAttackNum(myTankCoord);
                        if (coordAndValues.isEmpty() || canBeAttackNum <= coordAndValues.stream().min(Comparator.comparingInt(CoordAndValue::getValue)).get().getValue()) {
                            coordAndValues.add(CoordAndValue.builder().coord(myTankCoord).value(canBeAttackNum).build());
                        }
                    }
                } else {
                    //    上
                    Coord myTankCoord = new Coord(coord.x, coord.y + j);
                    if (!MapUtil.coordCanArrive(myTankCoord)) {
                        break;
                    } else {
                        Integer canBeAttackNum = MapUtil.getCanBeAttackNum(myTankCoord);
                        if (coordAndValues.isEmpty() || canBeAttackNum <= coordAndValues.stream().min(Comparator.comparingInt(CoordAndValue::getValue)).get().getValue()) {
                            coordAndValues.add(CoordAndValue.builder().coord(myTankCoord).value(canBeAttackNum).build());
                        }
                    }
                }
            }
        }
        Integer minValue = coordAndValues.stream().min(Comparator.comparingInt(CoordAndValue::getValue)).get().getValue();
        return coordAndValues.stream().filter(coordAndValue -> coordAndValue.getValue().equals(minValue)).map(CoordAndValue::getCoord)
                .collect(Collectors.toList());
    }


    /**
     * 该坐标是否有敌方坦克且能被攻击
     */
    public MapElement canAttackEnemy(Integer x, Integer y) {
        // 是否在地图中
        if (x < 0 || x >= width || y < 0 || y >= hight) {
            return BAR;
        }
        MapElement mapElement = maps.get(new Coord(x, y));
        if (mapElement == BAR || mapElement == NPC) {
            //碰到障碍物，无法攻击
            return BAR;
        }
        //敌方坦克如果死亡，无法攻击
        if (mapElement == ENEMY_ARMATA1) {
            return Condition.enemyArmata1.shengyushengming > 0 ? ENEMY_ARMATA1 : BAR;
        } else if (mapElement == MapElement.ENEMY_ARMATA2) {
            return Condition.enemyArmata2.shengyushengming > 0 ? ENEMY_ARMATA2 : BAR;
        } else if (mapElement == MapElement.ENEMY_T90) {
            return Condition.enemyT90.shengyushengming > 0 ? ENEMY_T90 : BAR;
        } else if (mapElement == MapElement.ENEMY_K2PANTHER) {
            return Condition.enemyK2Panther.shengyushengming > 0 ? ENEMY_K2PANTHER : BAR;
        } else if (mapElement == MapElement.ENEMY_WZ123) {
            return Condition.enemyWZ123.shengyushengming > 0 ? ENEMY_WZ123 : BAR;
        }
        return WAY;
    }


    /**
     * 找出能攻击到的我方的列表
     */
    public List<MapElementAndDirection> canAttackMyList(Tank tank) {
        Coord coord = tank.coord;
        List<MapElementAndDirection> myTanks = new ArrayList<>();
        for (int i = 0; i < 4; i++) {
            //威胁有4个方向
            for (int j = 1; j < tank.shecheng + 1; j++) {
                //左
                if (i == 0) {
                    MapElement mapElement = canAttackMy(coord.x - j, coord.y);
                    if (mapElement == BAR) {
                        break;
                    } else if (mapElement == WAY) {
                        continue;
                    } else {
                        myTanks.add(MapElementAndDirection.builder().mapElement(mapElement).direction(Direction.LEFT).build());
                    }
                } else if (i == 1) {
                    //    右
                    MapElement mapElement = canAttackMy(coord.x + j, coord.y);
                    if (mapElement == BAR) {
                        break;
                    } else if (mapElement == WAY) {
                        continue;
                    } else {
                        myTanks.add(MapElementAndDirection.builder().mapElement(mapElement).direction(Direction.RIGHT).build());
                    }
                } else if (i == 2) {
                    //    上
                    MapElement mapElement = canAttackMy(coord.x, coord.y - j);
                    if (mapElement == BAR) {
                        break;
                    } else if (mapElement == WAY) {
                        continue;
                    } else {
                        myTanks.add(MapElementAndDirection.builder().mapElement(mapElement).direction(Direction.UP).build());
                    }
                } else {
                    //    下
                    MapElement mapElement = canAttackMy(coord.x, coord.y + j);
                    if (mapElement == BAR) {
                        break;
                    } else if (mapElement == WAY) {
                        continue;
                    } else {
                        myTanks.add(MapElementAndDirection.builder().mapElement(mapElement).direction(Direction.DOWN).build());
                    }
                }
            }
        }
        return myTanks;
    }


    /**
     * 该坐标是否有我方坦克且能被攻击
     */
    public MapElement canAttackMy(Integer x, Integer y) {
        // 是否在地图中
        if (x < 0 || x >= width || y < 0 || y >= hight) {
            return BAR;
        }
        MapElement mapElement = maps.get(new Coord(x, y));
        if (mapElement == BAR || mapElement == NPC) {
            //碰到障碍物，无法攻击
            return BAR;
        }
        //我方坦克如果死亡，无法攻击
        if (mapElement == MY_ARMATA1) {
            return Condition.myArmata1.shengyushengming > 0 ? MY_ARMATA1 : BAR;
        } else if (mapElement == MapElement.MY_ARMATA2) {
            return Condition.myArmata2.shengyushengming > 0 ? MY_ARMATA2 : BAR;
        } else if (mapElement == MapElement.MY_T90) {
            return Condition.myT90.shengyushengming > 0 ? MY_T90 : BAR;
        } else if (mapElement == MapElement.MY_K2PANTHER) {
            return Condition.myK2Panther.shengyushengming > 0 ? MY_K2PANTHER : BAR;
        } else if (mapElement == MapElement.MY_WZ123) {
            return Condition.myWZ123.shengyushengming > 0 ? MY_WZ123 : BAR;
        }
        return WAY;
    }

    public List<MapElementAndDirection> listNearWZ123Enemy() {
        Coord coord = Condition.myWZ123.coord;
        List<MapElementAndDirection> enemyTanks = new ArrayList<>();
        for (int i = 0; i < 4; i++) {
            //威胁有4个方向
            //左
            if (i == 0) {
                MapElement mapElement = canAttackEnemy(coord.x - 1, coord.y);
                if (mapElement != BAR && mapElement != WAY) {
                    enemyTanks.add(MapElementAndDirection.builder().mapElement(mapElement).direction(Direction.LEFT).build());
                }
            } else if (i == 1) {
                //    右
                MapElement mapElement = canAttackEnemy(coord.x + 1, coord.y);
                if (mapElement != BAR && mapElement != WAY) {
                    enemyTanks.add(MapElementAndDirection.builder().mapElement(mapElement).direction(Direction.RIGHT).build());
                }
            } else if (i == 2) {
                //    上
                MapElement mapElement = canAttackEnemy(coord.x, coord.y - 1);
                if (mapElement != BAR && mapElement != WAY) {
                    enemyTanks.add(MapElementAndDirection.builder().mapElement(mapElement).direction(Direction.UP).build());
                }
            } else {
                //    下
                MapElement mapElement = canAttackEnemy(coord.x, coord.y + 1);
                if (mapElement != BAR && mapElement != WAY) {
                    enemyTanks.add(MapElementAndDirection.builder().mapElement(mapElement).direction(Direction.DOWN).build());
                }
            }

        }
        return enemyTanks;
    }

    public boolean myCanArrive(int x, int y, MapElement fromElement) {
        // 是否在地图中
        if (x < 0 || x >= width || y < 0 || y >= hight) {
            return false;
        }
        MapElement mapElement = maps.get(new Coord(x, y));
        if (mapElement == fromElement) {
            return true;
        }
        if (mapElement == MapElement.BAR) {
            return false;
        }
        return mapElement != MapElement.ENEMY_ARMATA1
                && mapElement != MapElement.ENEMY_ARMATA2
                && mapElement != MapElement.ENEMY_K2PANTHER
                && mapElement != MapElement.ENEMY_T90
                && mapElement != MapElement.NPC
                && mapElement != MapElement.MY_ARMATA1
                && mapElement != MapElement.MY_ARMATA2
                && mapElement != MapElement.MY_K2PANTHER
                && mapElement != MapElement.MY_T90
                && mapElement != MapElement.MY_WZ123
                && mapElement != MapElement.ENEMY_WZ123;
    }
}
